package upbeat;


import upbeat.types.Cue;

/**
 *
 * This is the abstract class of the Conductor.  The Conductor in the Upbeat program will create a new
 * class which derives from this one.  Functionality in this abstract class provides an interface for
 * the {@link Manager} to use.  It also handles all input given to it by the Manager and puts it in an easy
 * to access format for the derived Conductor.
 * 
 * @author Matt
 */
abstract public class Conductor implements ConductorInterface{
	/**
	 * mMan is a member variable that is a pointer to the {@link Manager} with which this Conductor interacts.
	 * This pointer is needed in order to do things like add {@link Cue}s to the score.
	 */
	private Manager mMan;
	
	/**
	 * This handles all the input that the Conductor object is given by the {@link Manager}.  It provides an
	 * easy interface that the Upbeat-programmer implemented version of Conduct() can use to get at the input.
	 */
	protected DataHandler input;
	
	//TODO Provide accessor methods to these member variables
	
	protected Conductor() {
		input = new DataHandler();
	}
	
	/**
	 * This should be the only constructor that ever gets used
	 * @param man	pointer to the {@link Manager} object that this Conductor will be interacting with.
	 */
	protected Conductor( Manager man ) {
		mMan = man;
		input = new DataHandler();
	}
	
	protected final void AddCueToScore( Cue c, int time ) {
		Cue newCue = c.clone();
		newCue.setTime(time);
		mMan.AddCueToScore( newCue );
	}
	
	/**
	 * Sets the manager pointer
	 * @param man	pointer to the {@link Manager} object that this Conductor will be interacting with.
	 */
	public final void SetManager( Manager man ){
		mMan = man;
	}
	
	/**
	 * Gets the Manager.
	 * @return	pointer to the {@link Manager} object used by this Conductor
	 */
	protected final Manager GetManager() {
		return mMan;
	}
	
	/**
	 * This version of Conduct is called by the {@link Manager} at the very end of all the input.
	 * 
	 * @param currentMeasure	the current measure in the song.
	 * @param newData			the new data to be associated with this measure.
	 * @param done				a boolean value saying whether or not we are finished processing input.
	 * 							If this is set to false, then call the other version of Conduct.
	 */
	public final void Conduct( int currentMeasure, double newData, boolean done) throws Exception {
		input.SetMore( !done );
		Conduct( currentMeasure, newData );
	}
	
	/**
	 * Method called by the {@link Manager} to get the Conductor to generate some @{link Cue}s.
	 * 
	 * @param currentMeasure	the current measure of the song.
	 * @param newData			the new data to be associated with this measure.
	 */
	public final void Conduct( int currentMeasure, double newData ) throws Exception {
		input.FeedData( newData );
		Conduct(currentMeasure);
	}
	
	/**
	 * This will be the actual version of Conduct implemented by the Upbeat-programmer.
	 * 
	 * @param currentMeasure	the current measure of the song.
	 */
	abstract protected void Conduct( int currentMeasure ) throws Exception;
}